import Vue from 'vue'
import VueRouter from 'vue-router'
// 导入 store 对象
import store from '@/store/index.js'

// 导入需要的路由组件
// import Login from '@/views/Login/Login.vue'
const Login = () => import('@/views/Login/Login.vue')

// import Main from '@/views/Main/Main.vue'
const Main = () => import('@/views/Main/Main.vue')

// import Home from '@/views/Home/Home.vue'
const Home = () => import('@/views/Home/Home.vue')

// import User from '@/views/User/User.vue'
const User = () => import('@/views/User/User.vue')

// import Search from '@/views/Search/Search.vue'
const Search = () => import('@/views/Search/Search.vue')

// import SearchResult from '@/views/SearchResult/SearchResult.vue'
const SearchResult = () => import('@/views/SearchResult/SearchResult.vue')

// import ArticleDetail from '@/views/ArticleDetail/ArticleDetail.vue'
const ArticleDetail = () => import('@/views/ArticleDetail/ArticleDetail.vue')

// import UserEdit from '@/views/UserEdit/UserEdit.vue'
const UserEdit = () => import('@/views/UserEdit/UserEdit.vue')

// import Chat from '@/views/Chat/Chat.vue'
const Chat = () => import('@/views/Chat/Chat.vue')

// 1. 将 VueRouter 本身提供的 $router.push 方法转存到常量中
const originalPush = VueRouter.prototype.push
// 2. 自定义 $router.push 方法，在内部调用原生的 originalPush 方法进行路由跳转；并通过 .catch 捕获错误
VueRouter.prototype.push = function push(location, onResolve, onReject) {
  if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject)
  // 通过 .catch 捕获错误
  return originalPush.call(this, location).catch(err => err)
}

Vue.use(VueRouter)

const routes = [
  // 登录组件的路由规则（带有 name 属性的路由规则，叫做“命名路由”）
  { path: '/login', component: Login, name: 'login' },
  // 主页的路由规则
  {
    path: '/',
    component: Main,
    children: [
      // 首页的子路由规则（如果 path 为空字符串，表示“默认子路由”）
      { path: '', component: Home, name: 'home', meta: { top: 0, isRecordTop: true } },
      // 我的子路由规则
      { path: 'user', component: User, name: 'user' }
    ]
  },
  // 搜索页面的路由规则
  { path: '/search', component: Search, name: 'search' },
  // 搜索结果页的路由规则 this.$route.params.kw
  { path: '/search/:kw', component: SearchResult, name: 'search-result', props: true },
  // 文章详情页的路由规则；注意：path 路径中通过 : 指定的参数都是 params 路径参数；
  // 在路径后面，通过 ? 携带的参数都是 query 查询参数
  { path: '/article/:id', component: ArticleDetail, name: 'art-detail', props: true },
  // 编辑用户简介的路由规则
  { path: '/user/edit', component: UserEdit, name: 'user-edit' },
  // 智能聊天的路由规则
  { path: '/chat', component: Chat, name: 'chat' }
]

const router = new VueRouter({
  routes
})

// pathArr 中存放的，是所有有权限的路径地址
const pathArr = ['/user', '/user/edit']

// 声明全局前置守卫
router.beforeEach((to, from, next) => {
  // 判断 from 中是否包含元信息
  if (from.meta.isRecordTop) {
    // 把滚动条纵向的位置，记录到 meta.top 中
    from.meta.top = window.scrollY
  }

  if (pathArr.indexOf(to.path) !== -1) {
    // 访问的是有权限的页面，需要进行登录的判断
    // 1. 从 vuex 中获取 token 的值
    const tokenStr = store.state.tokenInfo.token
    // 2. 判断 token 的值是否存在：
    // 2.1 如果 token 的值存在，证明已登录，则直接放行 next()
    // 2.2 如果 token 的值不存在，证明未登录，则强制跳转到登录页 next('/login')
    if (tokenStr) {
      // 登录了，直接放行
      next()
    } else {
      // /movie?id=3
      // to.path     ->   /movie
      // to.fullPath ->   /movie?id=3
      // 未登录，强制跳转到登录页
      // to 这个对象，表示访问未遂的那个路由对象
      next('/login?pre=' + to.fullPath)
    }
  } else {
    // 访问的不是有权限的页面，直接放行
    next()
  }
})

export default router
